#pragma once

#ifndef SCRPC_CLIENT_H
#define SCRPC_CLIENT_H

#include <muduo/net/TcpClient.h>
#include <muduo/net/EventLoop.h>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <unordered_map>

#include "common.h"

namespace scRpc
{
	
	// RpcClient 类 客户端
	// 发起请求 处理响应
	class RpcClient
	{
	private:
		/* data */
		// 字段
		struct ResponseWaiter {
    	    std::mutex mtx;
    	    std::condition_variable cv;
    	    nlohmann::json ans;
    	    bool received = false;
    	};

		muduo::net::TcpClient client_;		// muduo库的TcpClient对象，用于创建和管理TCP客户端
    	muduo::net::TcpConnectionPtr conn_;	// 当前连接的TcpConnection对象，表示与服务器的TCP连接
		std::atomic<int> curId_{0};			// 请求Id 每一个都唯一  具有原子性
		std::unordered_map<int, std::shared_ptr<ResponseWaiter>> waiters_;
    	std::mutex waitersMutex_;

		// 私有方法
		// 处理与服务器的连接事件
		void OnConnection(const muduo::net::TcpConnectionPtr& conn);

		// 处理接收到的信息
		void OnMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp time);
	public:
		// 构造函数，初始化RpcClient实例
    	// loop：事件循环，负责处理异步事件
    	// serverAddr：服务器地址，表示目标RPC服务器的地址和端口
		RpcClient(muduo::net::EventLoop* loop, const muduo::net::InetAddress& serverAddr);

		// 发起Rpc 请求 调用方法 传参
		// method：请求的RPC方法名
    	// params：传递给RPC方法的参数
    	// timeoutMs：请求超时时间，默认值为3000毫秒
		nlohmann::json Call(const std::string& method, const nlohmann::json& params, int timeoutMs = 3000);
		~RpcClient();
	};
	
} // namespace scRpc


#endif